package org.zero;

import java.util.function.Predicate;

/**
 * @author Zero (cnzeropro@qq.com)
 * @since 2023/4/25
 */
public class LogicalOperatorHelper {
    private boolean result;

    private LogicalOperatorHelper(boolean result) {
        this.result = result;
    }

    public static <T> LogicalOperatorHelper init(Predicate<T> predicate, T obj) {
        return new LogicalOperatorHelper(predicate.test(obj));
    }

    public <T> LogicalOperatorHelper and(Predicate<T> predicate, T... objs) {
        for (T obj : objs) {
            result = result && predicate.test(obj);
        }
        return this;
    }

    public <T> LogicalOperatorHelper negateAnd(Predicate<T> predicate, T... objs) {
        negate();
        return and(predicate, objs);
    }

    public <T> LogicalOperatorHelper and(T obj, Predicate<T>... predicates) {
        for (Predicate<T> p : predicates) {
            result = result && p.test(obj);
        }
        return this;
    }

    public <T> LogicalOperatorHelper negateAnd(T obj, Predicate<T>... predicates) {
        negate();
        return and(obj, predicates);
    }

    public <T> LogicalOperatorHelper or(Predicate<T> predicate, T... objs) {
        for (T obj : objs) {
            result = result || predicate.test(obj);
        }
        return this;
    }

    public <T> LogicalOperatorHelper negateOr(Predicate<T> predicate, T... objs) {
        negate();
        return or(predicate, objs);
    }

    public <T> LogicalOperatorHelper or(T obj, Predicate<T>... predicates) {
        for (Predicate<T> predicate : predicates) {
            result = result || predicate.test(obj);
        }
        return this;
    }

    public <T> LogicalOperatorHelper negateOr(T obj, Predicate<T>... predicates) {
        negate();
        return or(obj, predicates);
    }

    public LogicalOperatorHelper negate() {
        result = !result;
        return this;
    }

    public boolean result() {
        return result;
    }
}
